using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
using SeataNet.Core.Context;
using SeataNet.Core.Common;
using SeataNet.Core.Exceptions;
using System.Text.Json;

namespace SeataNet.Core.TCC
{
    /// <summary>
    /// TCC事务上下文
    ///
    /// 存储TCC模式全局事务的运行时信息和状态。
    ///
    /// 职责：
    /// - 跟踪全局事务的XID、状态、阶段、超时时间
    /// - 管理所有分支事务的上下文列表（Branches）
    /// - 记录事务的开始和结束时间
    /// - 提供事务生命周期的元数据
    ///
    /// 数据结构：
    /// - Xid：全局事务唯一标识符（由TC分配）
    /// - TransactionName：事务名称（用于日志和监控）
    /// - Timeout：事务超时时间（毫秒）
    /// - Status：事务状态（Trying/Confirming/Confirmed/Canceling/Canceled等）
    /// - Phase：事务阶段（Try/Confirm/Cancel）
    /// - Branches：所有分支事务的上下文列表
    /// - StartTime：事务开始时间（UTC）
    /// - EndTime：事务结束时间（UTC，可能为null）
    ///
    /// 生命周期：
    /// ```
    /// 1. Begin：创建上下文，Status=Trying, Phase=Try
    /// 2. Try阶段：执行业务逻辑，添加分支到Branches列表
    /// 3. Commit路径：Status=Confirming, Phase=Confirm → Status=Confirmed
    /// 4. Rollback路径：Status=Canceling, Phase=Cancel → Status=Canceled
    /// 5. 完成：设置EndTime，清理上下文
    /// ```
    ///
    /// 使用场景：
    /// - DefaultTccTransactionManager内部使用，缓存在_transactionContexts中
    /// - 监控和日志记录，提供事务元数据
    /// - 事务恢复，根据上下文恢复事务状态
    ///
    /// 线程安全：
    /// - 通常在单线程中使用（AsyncLocal隔离）
    /// - Branches列表不是线程安全的，需要外部同步
    /// - DefaultTccTransactionManager使用ConcurrentDictionary存储上下文
    ///
    /// 注意事项：
    /// - 所有时间使用UTC时间（避免时区问题）
    /// - EndTime为null表示事务未完成
    /// - Branches列表按添加顺序排列
    /// - 上下文仅存储在内存中（不持久化）
    /// - 事务完成后应清理上下文（避免内存泄漏）
    /// </summary>
    public class TccTransactionContext
    {
        /// <summary>
        /// 全局事务ID
        ///
        /// 全局事务的唯一标识符，由TC生成。
        ///
        /// 格式：IP:端口:时间戳:序列号
        /// 示例："192.168.1.100:8091:1703123456789:5678"
        ///
        /// 用途：
        /// - 标识全局事务
        /// - 关联所有分支事务
        /// - 传播到所有参与者
        /// - 作为_transactionContexts字典的键
        /// </summary>
        public string Xid { get; set; }

        /// <summary>
        /// 事务名称
        ///
        /// 用于日志和监控标识的事务名称。
        ///
        /// 推荐格式：
        /// - 业务名称：如"place-order"、"transfer-money"
        /// - 服务+方法：如"OrderService.CreateOrder"
        ///
        /// 用途：
        /// - 日志记录（方便查询和定位）
        /// - 监控统计（按事务名称聚合）
        /// - 问题排查（快速识别业务场景）
        /// </summary>
        public string TransactionName { get; set; }

        /// <summary>
        /// 超时时间（毫秒）
        ///
        /// 全局事务的超时时间，超过此时间TC会自动回滚。
        ///
        /// 默认值：60000ms（60秒）
        /// 推荐值：
        /// - 快速业务：5000-30000ms
        /// - 正常业务：60000-300000ms
        /// - 长时间业务：300000+ms
        ///
        /// 注意事项：
        /// - 超时时间从StartTime开始计算
        /// - TC定期检查超时事务
        /// - 超时后TC发起自动回滚
        /// - 应根据业务实际耗时合理设置
        /// </summary>
        public int Timeout { get; set; }

        /// <summary>
        /// 事务状态
        ///
        /// 标识全局事务的当前状态（TccTransactionStatus枚举）。
        ///
        /// 状态流转：
        /// - Trying：Try阶段执行中
        /// - Confirming：Confirm阶段执行中（提交路径）
        /// - Confirmed：Confirm完成（最终状态）
        /// - Canceling：Cancel阶段执行中（回滚路径）
        /// - Canceled：Cancel完成（最终状态）
        /// - ConfirmFailed：Confirm失败（需要重试或人工介入）
        /// - CancelFailed：Cancel失败（需要重试或人工介入）
        ///
        /// 注意事项：
        /// - 状态变更需要线程安全处理
        /// - 最终状态：Confirmed、Canceled
        /// - Failed状态需要TC异步重试
        /// </summary>
        public TccTransactionStatus Status { get; set; }

        /// <summary>
        /// 事务阶段
        ///
        /// 标识全局事务当前所处的阶段（TccTransactionPhase枚举）。
        ///
        /// 阶段说明：
        /// - Try：一阶段，预留资源
        /// - Confirm：二阶段成功路径，确认提交
        /// - Cancel：二阶段失败路径，释放资源
        ///
        /// 与Status的区别：
        /// - Phase：表示阶段（Try/Confirm/Cancel）
        /// - Status：表示状态（Trying/Confirming/Confirmed等）
        /// - Phase更粗粒度，Status更细粒度
        ///
        /// 注意事项：
        /// - Try阶段：Phase=Try, Status=Trying
        /// - Confirm阶段：Phase=Confirm, Status=Confirming/Confirmed/ConfirmFailed
        /// - Cancel阶段：Phase=Cancel, Status=Canceling/Canceled/CancelFailed
        /// </summary>
        public TccTransactionPhase Phase { get; set; }

        /// <summary>
        /// 分支事务列表
        ///
        /// 该全局事务下所有分支事务的上下文列表。
        ///
        /// 每个分支表示：
        /// - 一个TCC服务的参与
        /// - 一个Try/Confirm/Cancel方法的执行
        /// - 一个分支ID（BranchId）
        ///
        /// 用途：
        /// - 跟踪所有参与者
        /// - Confirm/Cancel阶段遍历所有分支
        /// - 监控分支状态
        /// - 统计分支数量和成功率
        ///
        /// 注意事项：
        /// - 列表按分支注册顺序排列
        /// - 不是线程安全的，需要外部同步
        /// - 每个分支有独立的BranchId和Status
        /// - Confirm/Cancel按注册顺序执行
        /// </summary>
        public List<TccBranchContext> Branches { get; set; }

        /// <summary>
        /// 开始时间
        ///
        /// 全局事务开始的UTC时间。
        ///
        /// 用途：
        /// - 计算事务持续时间
        /// - 判断是否超时（StartTime + Timeout）
        /// - 监控和审计
        /// - 性能分析
        ///
        /// 注意事项：
        /// - 使用UTC时间避免时区问题
        /// - 在DefaultTccTransactionManager.BeginAsync()中设置
        /// - 不应在执行过程中修改
        /// </summary>
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 结束时间
        ///
        /// 全局事务结束的UTC时间（可能为null）。
        ///
        /// null：事务尚未完成
        /// 非null：事务已完成（提交或回滚）
        ///
        /// 用途：
        /// - 计算事务总耗时：EndTime - StartTime
        /// - 判断事务是否完成
        /// - 监控和统计
        /// - 性能分析
        ///
        /// 注意事项：
        /// - 使用UTC时间避免时区问题
        /// - 只有在Confirmed或Canceled状态下才设置
        /// - 中间状态（Confirming/Canceling）不设置EndTime
        /// - 用于判断事务是否完成
        /// </summary>
        public DateTime? EndTime { get; set; }
    }

    /// <summary>
    /// TCC分支事务上下文
    ///
    /// 存储TCC模式分支事务的运行时信息和状态。
    ///
    /// 职责：
    /// - 跟踪分支事务的ID、资源ID、服务名称、方法名称
    /// - 记录分支事务的状态和阶段
    /// - 存储方法参数和动作上下文（用于Confirm/Cancel调用）
    /// - 提供分支事务的元数据用于监控和审计
    ///
    /// 数据结构：
    /// - Xid：全局事务ID（关联到父事务）
    /// - BranchId：分支事务唯一标识符（由TC分配）
    /// - ResourceId：资源标识符（通常是服务名称）
    /// - ServiceName：TCC服务名称
    /// - MethodName：TCC方法名称
    /// - Args：方法参数数组
    /// - ActionContext：动作上下文（JSON格式的TccActionContext）
    /// - Status：分支事务状态
    /// - Phase：事务阶段（Try/Confirm/Cancel）
    /// - StartTime：分支事务开始时间（UTC）
    /// - CreatedTime：分支创建时间（UTC）
    /// - EndTime：分支事务结束时间（UTC，可能为null）
    ///
    /// 生命周期：
    /// ```
    /// 1. Register：创建分支上下文，分配BranchId，Status=Registered
    /// 2. Try阶段：Phase=Try, Status=Trying/TrySuccess/TryFailed
    /// 3. Confirm阶段：Phase=Confirm, Status=Confirming/Confirmed/ConfirmFailed
    /// 4. Cancel阶段：Phase=Cancel, Status=Canceling/Canceled/CancelFailed
    /// 5. 完成：设置EndTime
    /// ```
    ///
    /// 与全局事务的关系：
    /// - 一个全局事务（TccTransactionContext）包含多个分支事务（TccBranchContext）
    /// - 每个分支对应一个TCC服务的参与
    /// - 每个分支有独立的BranchId和Status
    /// - 所有分支共享同一个XID（全局事务ID）
    ///
    /// 使用场景：
    /// - DefaultTccTransactionManager.RegisterBranchAsync()创建分支上下文
    /// - 添加到TccTransactionContext.Branches列表
    /// - Confirm/Cancel阶段遍历所有分支
    /// - 监控和日志记录分支状态
    ///
    /// 线程安全：
    /// - 通常在单线程中使用（AsyncLocal隔离）
    /// - 属性访问不是线程安全的，需要外部同步
    /// - 添加到Branches列表时需要同步
    ///
    /// 注意事项：
    /// - 所有时间使用UTC时间（避免时区问题）
    /// - EndTime为null表示分支未完成
    /// - BranchId在注册成功后才有值
    /// - ActionContext为JSON格式，用于Confirm/Cancel阶段反序列化
    /// </summary>
    public class TccBranchContext
    {
        /// <summary>
        /// 全局事务ID
        ///
        /// 分支事务所属的全局事务ID。
        ///
        /// 用途：
        /// - 关联到父事务
        /// - 向TC注册分支时使用
        /// - 日志记录和问题排查
        /// </summary>
        public string Xid { get; set; }

        /// <summary>
        /// 分支事务ID
        ///
        /// TC分配的分支事务唯一标识符，用于标识全局事务中的一个分支。
        ///
        /// 分配时机：
        /// - 调用DefaultTccTransactionManager.RegisterBranchAsync()时由TC分配
        /// - 在Try方法执行前完成分配
        ///
        /// 用途：
        /// - 标识分支事务（全局唯一）
        /// - Confirm/Cancel阶段指定目标分支
        /// - 上报分支状态时使用
        /// - 监控和审计
        ///
        /// 范围：
        /// - 类型：long（64位整数）
        /// - TC保证在全局范围内唯一
        ///
        /// 注意事项：
        /// - 注册失败时BranchId可能为0或默认值
        /// - 不同全局事务的分支ID可能重复
        /// - 与XID配合使用才能唯一标识分支
        /// </summary>
        public long BranchId { get; set; }

        /// <summary>
        /// 资源ID
        ///
        /// 标识分支事务所属的资源（通常是服务名称）。
        ///
        /// 格式：
        /// - 服务名称：如"OrderService"、"InventoryService"
        /// - 或自定义的资源标识符
        ///
        /// 用途：
        /// - TC根据ResourceId路由分支事务到对应的RM
        /// - 标识分支事务操作的目标服务
        /// - 分支注册时传递给TC
        ///
        /// 注意事项：
        /// - 通常与ServiceName相同
        /// - TC根据ResourceId发送Confirm/Cancel指令
        /// </summary>
        public string ResourceId { get; set; }

        /// <summary>
        /// 服务名称
        ///
        /// TCC服务的名称，用于从TccServiceRegistry查找服务实例。
        ///
        /// 用途：
        /// - Confirm/Cancel阶段从TccServiceRegistry.GetService(serviceName)获取服务
        /// - 标识TCC服务
        /// - 日志记录
        ///
        /// 注意事项：
        /// - 必须与TccServiceRegistry中注册的服务名称一致
        /// - 通常由ITccService.ServiceName属性提供
        /// </summary>
        public string ServiceName { get; set; }

        /// <summary>
        /// 方法名称
        ///
        /// TCC Try方法的名称。
        ///
        /// 用途：
        /// - 日志记录和监控
        /// - 标识具体的TCC方法
        /// - 问题排查
        ///
        /// 注意事项：
        /// - 通常对应Try方法名称
        /// - Confirm和Cancel方法名称可能不同
        /// </summary>
        public string MethodName { get; set; }

        /// <summary>
        /// 方法参数
        ///
        /// Try方法的参数数组。
        ///
        /// 用途：
        /// - 传递给Try方法执行
        /// - 可能在Confirm/Cancel阶段使用
        /// - 日志记录（调试时）
        ///
        /// 注意事项：
        /// - 参数需要可序列化（用于存储到ActionContext）
        /// - 参数类型需要匹配Try方法签名
        /// </summary>
        public object[] Args { get; set; }

        /// <summary>
        /// 动作上下文
        ///
        /// JSON格式的TccActionContext对象，包含完整的方法调用信息。
        ///
        /// 内容：
        /// - ServiceName：服务名称
        /// - MethodName：方法名称
        /// - Parameters：参数字典
        /// - TryResult：Try阶段的执行结果
        /// - ExtraData：额外数据
        ///
        /// 用途：
        /// - Confirm/Cancel阶段反序列化为TccActionContext
        /// - 传递给ITccService.ConfirmAsync()/CancelAsync()
        /// - 存储Try阶段的执行结果
        ///
        /// 注意事项：
        /// - 使用JsonSerializer序列化和反序列化
        /// - 需要包含Confirm/Cancel所需的所有信息
        /// - 不应包含大对象或敏感信息
        /// </summary>
        public string ActionContext { get; set; }

        /// <summary>
        /// 分支状态
        ///
        /// 标识分支事务当前的执行状态（TccBranchStatus枚举）。
        ///
        /// 状态流转：
        /// - Registered：已注册
        /// - Trying：Try执行中
        /// - TrySuccess：Try成功
        /// - TryFailed：Try失败
        /// - Confirming：Confirm执行中
        /// - Confirmed：Confirm完成（最终状态）
        /// - ConfirmFailed：Confirm失败
        /// - Canceling：Cancel执行中
        /// - Canceled：Cancel完成（最终状态）
        /// - CancelFailed：Cancel失败
        ///
        /// 注意事项：
        /// - 状态变更需要上报给TC
        /// - 最终状态：Confirmed、Canceled
        /// - Failed状态需要TC异步重试
        /// </summary>
        public TccBranchStatus Status { get; set; }

        /// <summary>
        /// 事务阶段
        ///
        /// 标识分支事务当前所处的阶段（TccTransactionPhase枚举）。
        ///
        /// 阶段说明：
        /// - Try：一阶段，预留资源
        /// - Confirm：二阶段成功路径，确认提交
        /// - Cancel：二阶段失败路径，释放资源
        ///
        /// 注意事项：
        /// - 与Status配合使用
        /// - Phase=Try时，Status可能为Trying/TrySuccess/TryFailed
        /// - Phase=Confirm时，Status可能为Confirming/Confirmed/ConfirmFailed
        /// - Phase=Cancel时，Status可能为Canceling/Canceled/CancelFailed
        /// </summary>
        public TccTransactionPhase Phase { get; set; }

        /// <summary>
        /// 开始时间
        ///
        /// 分支事务开始的UTC时间。
        ///
        /// 用途：
        /// - 计算分支事务持续时间
        /// - 监控和审计
        /// - 性能分析
        ///
        /// 注意事项：
        /// - 使用UTC时间避免时区问题
        /// - 在分支注册时设置
        /// </summary>
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 创建时间
        ///
        /// 分支上下文创建的UTC时间。
        ///
        /// 用途：
        /// - 记录分支创建时间
        /// - 与StartTime可能略有不同
        /// - 监控和审计
        ///
        /// 注意事项：
        /// - 使用UTC时间避免时区问题
        /// - 通常与StartTime相同或接近
        /// </summary>
        public DateTime CreatedTime { get; set; }

        /// <summary>
        /// 结束时间
        ///
        /// 分支事务结束的UTC时间（可能为null）。
        ///
        /// null：分支尚未完成
        /// 非null：分支已完成（提交或回滚）
        ///
        /// 用途：
        /// - 计算分支总耗时：EndTime - StartTime
        /// - 判断分支是否完成
        /// - 监控和统计
        ///
        /// 注意事项：
        /// - 使用UTC时间避免时区问题
        /// - 只有在Confirmed或Canceled状态下才设置
        /// </summary>
        public DateTime? EndTime { get; set; }
    }

    /// <summary>
    /// TCC动作上下文
    ///
    /// 存储TCC方法调用的完整信息，用于在Confirm/Cancel阶段恢复执行上下文。
    ///
    /// 职责：
    /// - 存储Try方法的调用信息（服务名、方法名、参数）
    /// - 记录Try阶段的执行结果（TryResult）
    /// - 携带额外的业务数据（ExtraData）
    /// - 作为Confirm/Cancel方法的输入参数
    ///
    /// 数据结构：
    /// - ServiceName：TCC服务名称（用于从TccServiceRegistry查找服务）
    /// - MethodName：Try方法名称（用于日志和监控）
    /// - Parameters：方法参数字典（键值对形式）
    /// - TryResult：Try阶段返回的业务结果（可能为null）
    /// - ExtraData：业务自定义的额外数据（可选）
    ///
    /// 序列化与反序列化：
    /// ```
    /// // Try阶段：序列化为JSON存储到TccBranchContext.ActionContext
    /// var context = new TccActionContext
    /// {
    ///     ServiceName = "OrderService",
    ///     MethodName = "PlaceOrder",
    ///     Parameters = new Dictionary<string, object>
    ///     {
    ///         { "orderId", 1001 },
    ///         { "amount", 100.0m }
    ///     },
    ///     TryResult = orderId
    /// };
    /// var json = JsonSerializer.Serialize(context);
    ///
    /// // Confirm/Cancel阶段：从JSON反序列化恢复上下文
    /// var context = JsonSerializer.Deserialize<TccActionContext>(json);
    /// ```
    ///
    /// 使用场景：
    /// - Try阶段：TccTransactionInterceptor创建ActionContext并序列化
    /// - 注册分支：将序列化后的JSON存储到TccBranchContext.ActionContext
    /// - Confirm/Cancel阶段：反序列化ActionContext传递给业务方法
    /// - 业务代码：从ActionContext.Parameters获取原始参数
    ///
    /// 与TccBranchContext的关系：
    /// - TccBranchContext.ActionContext：JSON格式的TccActionContext
    /// - TccActionContext：反序列化后的对象形式
    /// - TccBranchContext包含TccActionContext的序列化数据
    ///
    /// 线程安全：
    /// - 每次Confirm/Cancel调用创建新实例，线程隔离
    /// - Parameters和ExtraData字典不是线程安全的
    /// - 通常在单线程中使用，无需同步
    ///
    /// 注意事项：
    /// - 所有属性必须可序列化（支持JSON序列化）
    /// - Parameters字典的值必须是可序列化类型
    /// - 避免存储大对象或敏感信息（影响性能和安全）
    /// - TryResult可能为null（Try方法无返回值）
    /// - ExtraData可选，不需要时可以为null
    /// </summary>
    public class TccActionContext
    {
        /// <summary>
        /// 服务名称
        ///
        /// TCC服务的名称，用于从TccServiceRegistry查找服务实例。
        ///
        /// 用途：
        /// - Confirm/Cancel阶段从TccServiceRegistry.GetService(serviceName)获取服务
        /// - 标识TCC服务的唯一名称
        /// - 日志记录和问题排查
        ///
        /// 示例：
        /// - "OrderService"：订单服务
        /// - "InventoryService"：库存服务
        /// - "AccountService"：账户服务
        ///
        /// 注意事项：
        /// - 必须与TccServiceRegistry中注册的服务名称一致
        /// - 通常由ITccService.ServiceName属性提供
        /// - 大小写敏感
        /// </summary>
        public string ServiceName { get; set; }

        /// <summary>
        /// 方法名称
        ///
        /// Try方法的名称，用于日志记录和监控。
        ///
        /// 用途：
        /// - 日志记录（标识具体的TCC方法）
        /// - 监控统计（按方法聚合）
        /// - 问题排查（快速定位业务方法）
        ///
        /// 示例：
        /// - "PlaceOrder"：下单方法
        /// - "DeductInventory"：扣减库存方法
        /// - "DeductBalance"：扣减余额方法
        ///
        /// 注意事项：
        /// - 通常对应Try方法的方法名
        /// - Confirm和Cancel方法名称可能不同（通过特性或约定指定）
        /// - 用于日志记录，建议使用有意义的名称
        /// </summary>
        public string MethodName { get; set; }

        /// <summary>
        /// 参数字典
        ///
        /// Try方法的参数，以键值对形式存储。
        ///
        /// 格式：
        /// - 键：参数名称（字符串）
        /// - 值：参数值（object类型，可以是任何可序列化类型）
        ///
        /// 用途：
        /// - 传递Try方法的输入参数
        /// - Confirm/Cancel阶段可以访问原始参数
        /// - 用于日志记录（调试时）
        ///
        /// 使用示例：
        /// ```csharp
        /// // Try阶段：构建参数字典
        /// var parameters = new Dictionary<string, object>
        /// {
        ///     { "orderId", 1001L },
        ///     { "userId", "user123" },
        ///     { "amount", 100.50m },
        ///     { "items", new[] { "item1", "item2" } }
        /// };
        ///
        /// // Confirm/Cancel阶段：从字典获取参数
        /// var orderId = (long)actionContext.Parameters["orderId"];
        /// var amount = (decimal)actionContext.Parameters["amount"];
        /// ```
        ///
        /// 注意事项：
        /// - 所有参数值必须可序列化（支持JSON序列化）
        /// - 避免存储复杂对象（如数据库连接、文件句柄）
        /// - 参数值类型需要与Try方法签名匹配
        /// - 字典的值是object类型，使用时需要类型转换
        /// - 可能为null（Try方法无参数）
        /// </summary>
        public Dictionary<string, object> Parameters { get; set; }

        /// <summary>
        /// Try阶段结果
        ///
        /// Try方法执行后返回的业务结果。
        ///
        /// 用途：
        /// - 存储Try阶段的执行结果（如生成的订单ID、预留的库存ID等）
        /// - Confirm/Cancel阶段可能需要使用此结果（如删除预留记录）
        /// - 用于日志记录和监控
        ///
        /// 使用示例：
        /// ```csharp
        /// // Try阶段：执行业务逻辑并返回结果
        /// public async Task<object> TryAsync(TccActionContext context)
        /// {
        ///     var orderId = await _repository.CreateOrderAsync(...);
        ///     context.TryResult = orderId;  // 存储Try结果
        ///     return orderId;
        /// }
        ///
        /// // Confirm阶段：使用Try结果
        /// public async Task<bool> ConfirmAsync(TccActionContext context)
        /// {
        ///     var orderId = (long)context.TryResult;
        ///     await _repository.ConfirmOrderAsync(orderId);  // 使用Try阶段生成的订单ID
        ///     return true;
        /// }
        ///
        /// // Cancel阶段：使用Try结果回滚
        /// public async Task<bool> CancelAsync(TccActionContext context)
        /// {
        ///     var orderId = (long)context.TryResult;
        ///     await _repository.DeleteOrderAsync(orderId);  // 删除Try阶段创建的订单
        ///     return true;
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 可能为null（Try方法无返回值或返回void）
        /// - 必须可序列化（支持JSON序列化）
        /// - 类型是object，使用时需要类型转换
        /// - 避免存储大对象（影响序列化性能）
        /// - Try失败时可能未设置此值
        /// </summary>
        public object TryResult { get; set; }

        /// <summary>
        /// 额外数据
        ///
        /// 业务自定义的额外数据，用于在Try/Confirm/Cancel之间传递信息。
        ///
        /// 格式：
        /// - 键：数据名称（字符串）
        /// - 值：数据值（object类型，可以是任何可序列化类型）
        ///
        /// 用途：
        /// - 传递业务自定义的上下文信息
        /// - 存储Try阶段的中间状态（如预留资源ID）
        /// - Confirm/Cancel阶段访问额外的业务数据
        ///
        /// 使用示例：
        /// ```csharp
        /// // Try阶段：存储额外数据
        /// public async Task<object> TryAsync(TccActionContext context)
        /// {
        ///     var reservationId = await ReserveInventoryAsync(...);
        ///
        ///     // 存储预留ID到ExtraData
        ///     context.ExtraData = new Dictionary<string, object>
        ///     {
        ///         { "reservationId", reservationId },
        ///         { "timestamp", DateTime.UtcNow }
        ///     };
        ///
        ///     return true;
        /// }
        ///
        /// // Confirm阶段：使用ExtraData
        /// public async Task<bool> ConfirmAsync(TccActionContext context)
        /// {
        ///     var reservationId = (long)context.ExtraData["reservationId"];
        ///     await ConfirmReservationAsync(reservationId);  // 确认预留
        ///     return true;
        /// }
        ///
        /// // Cancel阶段：使用ExtraData清理资源
        /// public async Task<bool> CancelAsync(TccActionContext context)
        /// {
        ///     var reservationId = (long)context.ExtraData["reservationId"];
        ///     await ReleaseReservationAsync(reservationId);  // 释放预留
        ///     return true;
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 可选字段，不需要时可以为null
        /// - 所有数据值必须可序列化（支持JSON序列化）
        /// - 避免存储大对象或敏感信息
        /// - 字典的值是object类型，使用时需要类型转换
        /// - 通常用于存储Try阶段生成的临时资源ID
        /// </summary>
        public Dictionary<string, object> ExtraData { get; set; }
    }

    /// <summary>
    /// TCC事务状态
    /// </summary>
    public enum TccTransactionStatus
    {
        /// <summary>
        /// 未知
        /// </summary>
        Unknown,

        /// <summary>
        /// 尝试中
        /// </summary>
        Trying,

        /// <summary>
        /// 确认中
        /// </summary>
        Confirming,

        /// <summary>
        /// 取消中
        /// </summary>
        Canceling,

        /// <summary>
        /// 已确认
        /// </summary>
        Confirmed,

        /// <summary>
        /// 已取消
        /// </summary>
        Canceled,

        /// <summary>
        /// 确认失败
        /// </summary>
        ConfirmFailed,

        /// <summary>
        /// 取消失败
        /// </summary>
        CancelFailed
    }

    /// <summary>
    /// TCC分支状态
    /// </summary>
    public enum TccBranchStatus
    {
        /// <summary>
        /// 未知
        /// </summary>
        Unknown,

        /// <summary>
        /// 已注册
        /// </summary>
        Registered,

        /// <summary>
        /// 尝试中
        /// </summary>
        Trying,

        /// <summary>
        /// 尝试成功
        /// </summary>
        TrySuccess,

        /// <summary>
        /// 尝试失败
        /// </summary>
        TryFailed,

        /// <summary>
        /// 确认中
        /// </summary>
        Confirming,

        /// <summary>
        /// 已确认
        /// </summary>
        Confirmed,

        /// <summary>
        /// 确认失败
        /// </summary>
        ConfirmFailed,

        /// <summary>
        /// 取消中
        /// </summary>
        Canceling,

        /// <summary>
        /// 已取消
        /// </summary>
        Canceled,

        /// <summary>
        /// 取消失败
        /// </summary>
        CancelFailed,

        /// <summary>
        /// 阶段完成
        /// </summary>
        PhaseDone,

        /// <summary>
        /// 失败
        /// </summary>
        Failed
    }

    /// <summary>
    /// TCC事务阶段
    /// </summary>
    public enum TccTransactionPhase
    {
        /// <summary>
        /// Try阶段
        /// </summary>
        Try,

        /// <summary>
        /// Confirm阶段
        /// </summary>
        Confirm,

        /// <summary>
        /// Cancel阶段
        /// </summary>
        Cancel
    }

    /// <summary>
    /// TCC服务接口
    ///
    /// 定义TCC模式业务服务的标准接口，规范Try-Confirm-Cancel三阶段方法。
    ///
    /// 职责：
    /// - 定义ServiceName属性（服务唯一标识符）
    /// - 定义TryAsync方法（一阶段：预留资源）
    /// - 定义ConfirmAsync方法（二阶段：确认提交）
    /// - 定义CancelAsync方法（二阶段：取消回滚）
    ///
    /// TCC三阶段说明：
    /// ```
    /// 1. Try阶段（一阶段）：
    ///    - 执行业务检查（如库存是否充足、余额是否足够）
    ///    - 预留业务资源（如冻结库存、冻结余额）
    ///    - 不实际提交，保持资源锁定状态
    ///    - 返回Try结果（如预留ID）
    ///
    /// 2. Confirm阶段（二阶段 - 成功路径）：
    ///    - Try成功后，TC发起Confirm
    ///    - 确认提交业务操作（如实际扣减库存、实际扣减余额）
    ///    - 使用Try阶段预留的资源
    ///    - 释放资源锁定
    ///    - 必须幂等（可重复执行，结果相同）
    ///
    /// 3. Cancel阶段（二阶段 - 失败路径）：
    ///    - Try失败或业务异常时，TC发起Cancel
    ///    - 取消业务操作（如释放冻结库存、释放冻结余额）
    ///    - 回滚到Try之前的状态
    ///    - 释放Try阶段预留的资源
    ///    - 必须幂等（可重复执行，结果相同）
    /// ```
    ///
    /// 实现示例：
    /// ```csharp
    /// public class InventoryTccService : ITccService
    /// {
    ///     public string ServiceName => "InventoryService";
    ///
    ///     // Try：冻结库存（预留资源）
    ///     public async Task<object> TryAsync(TccActionContext context)
    ///     {
    ///         var productId = (long)context.Parameters["productId"];
    ///         var quantity = (int)context.Parameters["quantity"];
    ///
    ///         // 检查库存是否充足
    ///         var available = await CheckInventoryAsync(productId, quantity);
    ///         if (!available) throw new InsufficientInventoryException();
    ///
    ///         // 冻结库存（不实际扣减）
    ///         var reservationId = await FreezeInventoryAsync(productId, quantity);
    ///         return reservationId;  // 返回预留ID
    ///     }
    ///
    ///     // Confirm：实际扣减库存（确认提交）
    ///     public async Task<bool> ConfirmAsync(TccActionContext context)
    ///     {
    ///         var reservationId = (long)context.TryResult;
    ///
    ///         // 实际扣减库存，删除预留记录（幂等）
    ///         await DeductInventoryAsync(reservationId);
    ///         return true;
    ///     }
    ///
    ///     // Cancel：释放冻结库存（取消回滚）
    ///     public async Task<bool> CancelAsync(TccActionContext context)
    ///     {
    ///         var reservationId = (long)context.TryResult;
    ///
    ///         // 释放冻结库存（幂等）
    ///         await UnfreezeInventoryAsync(reservationId);
    ///         return true;
    ///     }
    /// }
    /// ```
    ///
    /// 使用场景：
    /// - 需要精细控制事务逻辑的场景（库存扣减、余额冻结等）
    /// - 对性能要求较高的场景（无undo_log开销）
    /// - 业务逻辑复杂，无法用undo_log回滚的场景
    /// - 需要资源预留和释放的场景
    ///
    /// 服务注册：
    /// ```csharp
    /// // 注册TCC服务到TccServiceRegistry
    /// TccServiceRegistry.RegisterService(new InventoryTccService());
    /// TccServiceRegistry.RegisterService(new AccountTccService());
    /// ```
    ///
    /// 线程安全：
    /// - 实现类应该是无状态的（避免共享可变状态）
    /// - Try/Confirm/Cancel方法可能被并发调用
    /// - 使用数据库锁或分布式锁保护共享资源
    ///
    /// 注意事项：
    /// - ServiceName必须全局唯一（在TccServiceRegistry中）
    /// - Confirm和Cancel必须是幂等的（TC可能重试）
    /// - Try阶段应该预留资源，而不是直接修改（避免脏写）
    /// - Cancel阶段应该释放Try预留的资源（避免资源泄漏）
    /// - 实现类应该注册到TccServiceRegistry
    /// - Try/Confirm/Cancel方法应该快速执行（避免长时间阻塞）
    /// </summary>
    public interface ITccService
    {
        /// <summary>
        /// 服务名称
        ///
        /// TCC服务的唯一标识符，用于从TccServiceRegistry查找服务实例。
        ///
        /// 要求：
        /// - 必须全局唯一（在整个应用中）
        /// - 建议使用类名或业务名称（如"OrderService"、"InventoryService"）
        /// - 大小写敏感
        ///
        /// 用途：
        /// - TccServiceRegistry.RegisterService()时作为键
        /// - TccServiceRegistry.GetService()时查找服务
        /// - TccActionContext.ServiceName存储此值
        /// - 日志记录和监控
        ///
        /// 示例：
        /// - "OrderService"：订单服务
        /// - "InventoryService"：库存服务
        /// - "AccountService"：账户服务
        ///
        /// 注意事项：
        /// - 应该使用const或静态属性（避免每次创建新字符串）
        /// - 不能为null或空字符串
        /// - 服务重命名会导致Confirm/Cancel找不到服务
        /// </summary>
        string ServiceName { get; }

        /// <summary>
        /// 执行Try方法（一阶段：预留资源）
        ///
        /// TCC模式的第一阶段，执行业务检查并预留资源。
        ///
        /// 执行流程：
        /// 1. 从actionContext.Parameters获取业务参数
        /// 2. 执行业务规则检查（如库存是否充足、余额是否足够）
        /// 3. 预留业务资源（如冻结库存、冻结余额、创建预留记录）
        /// 4. 不实际提交业务操作（保持资源锁定状态）
        /// 5. 返回Try结果（如预留ID、预留记录等）
        ///
        /// 调用时机：
        /// - TccTransactionInterceptor.ExecuteAsync()执行时调用
        /// - 在全局事务的Try阶段
        /// - 在分支事务注册之前
        ///
        /// 返回值说明：
        /// - 返回Try阶段的执行结果（如预留ID）
        /// - 返回值会存储到actionContext.TryResult
        /// - Confirm/Cancel阶段可以使用此返回值
        /// - 可以返回null（无需返回结果）
        ///
        /// 异常处理：
        /// - 业务检查失败应该抛出异常（如库存不足、余额不足）
        /// - 抛出异常会导致全局事务回滚（TC发起Cancel）
        /// - 应该抛出有意义的业务异常（方便问题排查）
        ///
        /// 使用示例：
        /// ```csharp
        /// public async Task<object> TryAsync(TccActionContext context)
        /// {
        ///     // 1. 获取参数
        ///     var productId = (long)context.Parameters["productId"];
        ///     var quantity = (int)context.Parameters["quantity"];
        ///
        ///     // 2. 业务检查
        ///     var inventory = await _repository.GetInventoryAsync(productId);
        ///     if (inventory.Available < quantity)
        ///     {
        ///         throw new InsufficientInventoryException($"库存不足: 可用{inventory.Available}, 需要{quantity}");
        ///     }
        ///
        ///     // 3. 预留资源（冻结库存，不实际扣减）
        ///     var reservation = new InventoryReservation
        ///     {
        ///         ProductId = productId,
        ///         Quantity = quantity,
        ///         Status = "Frozen",
        ///         CreatedTime = DateTime.UtcNow
        ///     };
        ///     await _repository.CreateReservationAsync(reservation);
        ///
        ///     // 4. 返回预留ID（供Confirm/Cancel使用）
        ///     return reservation.Id;
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 不应该实际提交业务操作（如不应该直接扣减库存）
        /// - 应该预留资源（如创建预留记录、冻结库存）
        /// - 预留的资源应该有超时机制（避免永久锁定）
        /// - Try失败会导致全局事务回滚
        /// - 返回值应该包含Confirm/Cancel所需的信息
        /// </summary>
        /// <param name="actionContext">动作上下文，包含服务名、方法名、参数等信息</param>
        /// <returns>Try阶段执行结果，可能为null</returns>
        /// <exception cref="Exception">业务检查失败或预留资源失败时抛出异常</exception>
        Task<object> TryAsync(TccActionContext actionContext);

        /// <summary>
        /// 执行Confirm方法（二阶段：确认提交）
        ///
        /// TCC模式的第二阶段（成功路径），确认提交Try阶段预留的资源。
        ///
        /// 执行流程：
        /// 1. 从actionContext.TryResult获取Try阶段返回的结果（如预留ID）
        /// 2. 确认提交业务操作（如实际扣减库存、实际扣减余额）
        /// 3. 使用Try阶段预留的资源
        /// 4. 删除预留记录或更新预留状态为已确认
        /// 5. 释放资源锁定
        /// 6. 返回true表示成功，false表示失败
        ///
        /// 调用时机：
        /// - Try阶段全部成功后，TC发起Confirm
        /// - DefaultTccTransactionManager.CommitAsync()执行时调用
        /// - ExecuteConfirmAsync()方法内部调用
        ///
        /// 幂等性要求：
        /// - 必须是幂等的（TC可能重试，多次执行结果相同）
        /// - 幂等实现方式：
        ///   - 方式1：检查预留记录状态，已确认则直接返回true
        ///   - 方式2：使用数据库唯一约束（如预留ID作为主键）
        ///   - 方式3：使用分布式锁（如Redis锁）
        ///
        /// 返回值说明：
        /// - true：Confirm成功
        /// - false：Confirm失败（TC会异步重试）
        ///
        /// 异常处理：
        /// - 应该捕获异常并返回false（不抛出异常）
        /// - TC会异步重试失败的Confirm
        /// - 重试次数耗尽后需要人工介入
        ///
        /// 使用示例：
        /// ```csharp
        /// public async Task<bool> ConfirmAsync(TccActionContext context)
        /// {
        ///     try
        ///     {
        ///         // 1. 获取Try阶段返回的预留ID
        ///         var reservationId = (long)context.TryResult;
        ///
        ///         // 2. 查询预留记录
        ///         var reservation = await _repository.GetReservationAsync(reservationId);
        ///         if (reservation == null)
        ///         {
        ///             _logger.LogWarning($"预留记录不存在: {reservationId}");
        ///             return true;  // 幂等：已删除视为成功
        ///         }
        ///
        ///         // 3. 幂等检查：如果已确认，直接返回成功
        ///         if (reservation.Status == "Confirmed")
        ///         {
        ///             return true;
        ///         }
        ///
        ///         // 4. 实际扣减库存
        ///         await _repository.DeductInventoryAsync(reservation.ProductId, reservation.Quantity);
        ///
        ///         // 5. 删除预留记录或更新状态
        ///         await _repository.DeleteReservationAsync(reservationId);
        ///         // 或：await _repository.UpdateReservationStatusAsync(reservationId, "Confirmed");
        ///
        ///         return true;
        ///     }
        ///     catch (Exception ex)
        ///     {
        ///         _logger.LogError(ex, $"Confirm失败: {context.ServiceName}");
        ///         return false;  // 返回false，TC会重试
        ///     }
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 必须是幂等的（可重复执行，结果相同）
        /// - 应该快速执行（避免长时间阻塞）
        /// - 失败应该返回false而非抛出异常
        /// - 不应该假设只执行一次（TC可能重试）
        /// - 应该检查预留记录状态（实现幂等）
        /// </summary>
        /// <param name="actionContext">动作上下文，包含Try结果、参数等信息</param>
        /// <returns>true表示成功，false表示失败（TC会重试）</returns>
        Task<bool> ConfirmAsync(TccActionContext actionContext);

        /// <summary>
        /// 执行Cancel方法（二阶段：取消回滚）
        ///
        /// TCC模式的第二阶段（失败路径），取消Try阶段预留的资源。
        ///
        /// 执行流程：
        /// 1. 从actionContext.TryResult获取Try阶段返回的结果（如预留ID）
        /// 2. 取消业务操作（如释放冻结库存、释放冻结余额）
        /// 3. 删除预留记录或更新预留状态为已取消
        /// 4. 释放Try阶段预留的资源
        /// 5. 回滚到Try之前的状态
        /// 6. 返回true表示成功，false表示失败
        ///
        /// 调用时机：
        /// - Try阶段失败或业务异常时，TC发起Cancel
        /// - DefaultTccTransactionManager.RollbackAsync()执行时调用
        /// - ExecuteCancelAsync()方法内部调用
        /// - TC超时自动回滚时调用
        ///
        /// 幂等性要求：
        /// - 必须是幂等的（TC可能重试，多次执行结果相同）
        /// - 幂等实现方式：
        ///   - 方式1：检查预留记录状态，已取消则直接返回true
        ///   - 方式2：使用数据库唯一约束（如预留ID作为主键）
        ///   - 方式3：使用分布式锁（如Redis锁）
        ///
        /// 返回值说明：
        /// - true：Cancel成功
        /// - false：Cancel失败（TC会异步重试）
        ///
        /// 异常处理：
        /// - 应该捕获异常并返回false（不抛出异常）
        /// - TC会异步重试失败的Cancel
        /// - 重试次数耗尽后需要人工介入
        ///
        /// 使用示例：
        /// ```csharp
        /// public async Task<bool> CancelAsync(TccActionContext context)
        /// {
        ///     try
        ///     {
        ///         // 1. 获取Try阶段返回的预留ID
        ///         var reservationId = (long)context.TryResult;
        ///
        ///         // 2. 查询预留记录
        ///         var reservation = await _repository.GetReservationAsync(reservationId);
        ///         if (reservation == null)
        ///         {
        ///             _logger.LogWarning($"预留记录不存在: {reservationId}");
        ///             return true;  // 幂等：已删除视为成功
        ///         }
        ///
        ///         // 3. 幂等检查：如果已取消，直接返回成功
        ///         if (reservation.Status == "Canceled")
        ///         {
        ///             return true;
        ///         }
        ///
        ///         // 4. 释放冻结库存（如果使用冻结字段）
        ///         await _repository.UnfreezeInventoryAsync(reservation.ProductId, reservation.Quantity);
        ///
        ///         // 5. 删除预留记录或更新状态
        ///         await _repository.DeleteReservationAsync(reservationId);
        ///         // 或：await _repository.UpdateReservationStatusAsync(reservationId, "Canceled");
        ///
        ///         return true;
        ///     }
        ///     catch (Exception ex)
        ///     {
        ///         _logger.LogError(ex, $"Cancel失败: {context.ServiceName}");
        ///         return false;  // 返回false，TC会重试
        ///     }
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 必须是幂等的（可重复执行，结果相同）
        /// - 应该快速执行（避免长时间阻塞）
        /// - 失败应该返回false而非抛出异常
        /// - 不应该假设只执行一次（TC可能重试）
        /// - Cancel失败可能导致资源泄漏（需要定时清理）
        /// - 应该检查预留记录状态（实现幂等）
        /// </summary>
        /// <param name="actionContext">动作上下文，包含Try结果、参数等信息</param>
        /// <returns>true表示成功，false表示失败（TC会重试）</returns>
        Task<bool> CancelAsync(TccActionContext actionContext);
    }

    /// <summary>
    /// TCC服务注册表
    ///
    /// 全局TCC服务注册表，管理所有TCC服务实例的注册、查找和移除。
    ///
    /// 职责：
    /// - 提供TCC服务注册功能（RegisterService）
    /// - 提供TCC服务查找功能（GetService）
    /// - 提供TCC服务移除功能（RemoveService）
    /// - 提供所有服务名称查询（GetServiceNames）
    /// - 提供清空所有服务功能（Clear）
    ///
    /// 工作原理：
    /// ```
    /// // 应用启动时注册TCC服务
    /// TccServiceRegistry.RegisterService(new OrderTccService());
    /// TccServiceRegistry.RegisterService(new InventoryTccService());
    /// TccServiceRegistry.RegisterService(new AccountTccService());
    ///
    /// // Confirm/Cancel阶段查找服务
    /// var service = TccServiceRegistry.GetService("OrderService");
    /// await service.ConfirmAsync(actionContext);
    /// ```
    ///
    /// 存储结构：
    /// - 使用ConcurrentDictionary<string, ITccService>存储服务
    /// - 键：服务名称（ServiceName）
    /// - 值：TCC服务实例（ITccService）
    /// - 线程安全，支持并发访问
    ///
    /// 使用场景：
    /// - 应用启动：注册所有TCC服务实例
    /// - Confirm阶段：DefaultTccTransactionManager.ExecuteConfirmAsync()查找服务
    /// - Cancel阶段：DefaultTccTransactionManager.ExecuteCancelAsync()查找服务
    /// - 监控诊断：GetServiceNames()获取所有已注册服务
    /// - 应用关闭：Clear()清空所有服务
    ///
    /// 注册方式：
    /// ```csharp
    /// // 方式1：手动注册（Program.cs或Startup.cs）
    /// TccServiceRegistry.RegisterService(new OrderTccService());
    /// TccServiceRegistry.RegisterService(new InventoryTccService());
    ///
    /// // 方式2：通过依赖注入注册（推荐）
    /// services.AddSingleton<OrderTccService>();
    /// services.AddHostedService<TccServiceRegistrator>();  // 启动时自动注册
    ///
    /// public class TccServiceRegistrator : IHostedService
    /// {
    ///     private readonly IServiceProvider _serviceProvider;
    ///
    ///     public Task StartAsync(CancellationToken cancellationToken)
    ///     {
    ///         var orderService = _serviceProvider.GetService<OrderTccService>();
    ///         TccServiceRegistry.RegisterService(orderService);
    ///         return Task.CompletedTask;
    ///     }
    /// }
    /// ```
    ///
    /// 线程安全：
    /// - 类本身是静态的，全局共享
    /// - _services使用ConcurrentDictionary，线程安全
    /// - RegisterService/GetService/RemoveService可以并发调用
    ///
    /// 注意事项：
    /// - 服务名称必须全局唯一（重复注册会被忽略）
    /// - 应用启动时完成所有服务注册
    /// - 服务实例应该是无状态的（避免线程安全问题）
    /// - 服务实例通常注册为Singleton生命周期
    /// - 服务未注册会导致Confirm/Cancel查找失败
    /// - 应用关闭时应调用Clear()释放资源
    /// </summary>
    public static class TccServiceRegistry
    {
        private static readonly ConcurrentDictionary<string, ITccService> _services = new();

        /// <summary>
        /// 注册TCC服务
        ///
        /// 将TCC服务实例注册到全局注册表，供Confirm/Cancel阶段查找使用。
        ///
        /// 执行流程：
        /// 1. 检查service参数是否为null（为null抛出ArgumentNullException）
        /// 2. 检查service.ServiceName是否为空（为空抛出ArgumentException）
        /// 3. 调用_services.TryAdd(serviceName, service)添加到字典
        ///    - 如果serviceName已存在，TryAdd返回false，不覆盖现有服务
        ///    - 如果serviceName不存在，TryAdd返回true，添加成功
        ///
        /// 调用时机：
        /// - 应用启动时（Program.cs或Startup.cs）
        /// - 在调用任何TCC事务之前
        /// - 通常在依赖注入容器构建完成后
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：手动注册
        /// var orderService = new OrderTccService(orderRepository, logger);
        /// TccServiceRegistry.RegisterService(orderService);
        ///
        /// // 示例2：从依赖注入容器注册
        /// var serviceProvider = services.BuildServiceProvider();
        /// TccServiceRegistry.RegisterService(serviceProvider.GetService<OrderTccService>());
        /// TccServiceRegistry.RegisterService(serviceProvider.GetService<InventoryTccService>());
        ///
        /// // 示例3：批量注册
        /// var tccServices = new ITccService[]
        /// {
        ///     new OrderTccService(),
        ///     new InventoryTccService(),
        ///     new AccountTccService()
        /// };
        /// foreach (var service in tccServices)
        /// {
        ///     TccServiceRegistry.RegisterService(service);
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - service不能为null，否则抛出ArgumentNullException
        /// - service.ServiceName不能为空，否则抛出ArgumentException
        /// - 重复注册相同ServiceName会被忽略（保留第一次注册的实例）
        /// - 应该在应用启动时完成所有服务注册
        /// - 注册后无法修改服务实例（除非先RemoveService）
        /// </summary>
        /// <param name="service">TCC服务实例，不能为null</param>
        /// <exception cref="ArgumentNullException">service为null时抛出</exception>
        /// <exception cref="ArgumentException">service.ServiceName为空时抛出</exception>
        public static void RegisterService(ITccService service)
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            if (string.IsNullOrEmpty(service.ServiceName))
            {
                throw new ArgumentException("服务名称不能为空", nameof(service));
            }

            _services.TryAdd(service.ServiceName, service);
        }

        /// <summary>
        /// 获取TCC服务
        ///
        /// 根据服务名称从注册表中查找TCC服务实例。
        ///
        /// 执行流程：
        /// 1. 调用_services.TryGetValue(serviceName, out var service)查找服务
        ///    - 找到：out参数service设置为服务实例，返回true
        ///    - 未找到：out参数service设置为null，返回false
        /// 2. 返回service（可能为null）
        ///
        /// 调用时机：
        /// - DefaultTccTransactionManager.ExecuteConfirmAsync()查找服务
        /// - DefaultTccTransactionManager.ExecuteCancelAsync()查找服务
        /// - 监控和诊断工具查询服务
        ///
        /// 返回值说明：
        /// - 返回TCC服务实例（ITccService）
        /// - 服务未注册时返回null
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：查找服务并调用Confirm
        /// var service = TccServiceRegistry.GetService("OrderService");
        /// if (service != null)
        /// {
        ///     await service.ConfirmAsync(actionContext);
        /// }
        /// else
        /// {
        ///     _logger.LogError($"未找到TCC服务: OrderService");
        /// }
        ///
        /// // 示例2：查找服务并调用Cancel
        /// var service = TccServiceRegistry.GetService(actionContext.ServiceName);
        /// if (service == null)
        /// {
        ///     throw new InvalidOperationException($"TCC服务未注册: {actionContext.ServiceName}");
        /// }
        /// var result = await service.CancelAsync(actionContext);
        /// ```
        ///
        /// 注意事项：
        /// - serviceName为null或空字符串时返回null
        /// - 服务未注册时返回null（不抛出异常）
        /// - 调用方应该检查返回值是否为null
        /// - 大小写敏感（"OrderService" != "orderservice"）
        /// - 线程安全，可以并发调用
        /// </summary>
        /// <param name="serviceName">服务名称，大小写敏感</param>
        /// <returns>TCC服务实例，未找到返回null</returns>
        public static ITccService GetService(string serviceName)
        {
            _services.TryGetValue(serviceName, out var service);
            return service;
        }

        /// <summary>
        /// 移除TCC服务
        ///
        /// 从注册表中移除指定的TCC服务。
        ///
        /// 执行流程：
        /// 1. 调用_services.TryRemove(serviceName, out _)移除服务
        ///    - 找到：移除服务，返回true
        ///    - 未找到：不执行任何操作，返回false
        ///
        /// 调用时机：
        /// - 服务下线或停用时
        /// - 动态卸载TCC服务时
        /// - 应用关闭前清理资源时
        ///
        /// 返回值说明：
        /// - true：服务存在且成功移除
        /// - false：服务不存在，无需移除
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：移除单个服务
        /// var removed = TccServiceRegistry.RemoveService("OrderService");
        /// if (removed)
        /// {
        ///     _logger.LogInformation("OrderService已移除");
        /// }
        ///
        /// // 示例2：服务下线时移除
        /// public async Task OnServiceShutdownAsync(string serviceName)
        /// {
        ///     var removed = TccServiceRegistry.RemoveService(serviceName);
        ///     if (removed)
        ///     {
        ///         _logger.LogInformation($"服务已下线: {serviceName}");
        ///     }
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - serviceName为null或空字符串时返回false
        /// - 移除后该服务的Confirm/Cancel将无法执行
        /// - 应该确保没有正在执行的事务使用该服务
        /// - 移除后可以重新注册相同名称的服务
        /// - 线程安全，可以并发调用
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <returns>true表示成功移除，false表示服务不存在</returns>
        public static bool RemoveService(string serviceName)
        {
            return _services.TryRemove(serviceName, out _);
        }

        /// <summary>
        /// 获取所有已注册的服务名称
        ///
        /// 返回所有已注册到注册表的TCC服务名称列表。
        ///
        /// 执行流程：
        /// 1. 返回_services.Keys（ConcurrentDictionary的键集合）
        ///
        /// 调用时机：
        /// - 监控和诊断：查看所有已注册服务
        /// - 健康检查：检查必需的服务是否已注册
        /// - 调试和日志：记录当前注册的服务
        ///
        /// 返回值说明：
        /// - 返回IEnumerable<string>：所有服务名称的集合
        /// - 如果没有注册任何服务，返回空集合
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：查看所有已注册服务
        /// var serviceNames = TccServiceRegistry.GetServiceNames();
        /// foreach (var name in serviceNames)
        /// {
        ///     _logger.LogInformation($"已注册TCC服务: {name}");
        /// }
        ///
        /// // 示例2：健康检查
        /// var requiredServices = new[] { "OrderService", "InventoryService", "AccountService" };
        /// var registeredServices = TccServiceRegistry.GetServiceNames().ToList();
        /// var missingServices = requiredServices.Except(registeredServices).ToList();
        /// if (missingServices.Any())
        /// {
        ///     _logger.LogWarning($"缺少TCC服务: {string.Join(", ", missingServices)}");
        /// }
        ///
        /// // 示例3：统计服务数量
        /// var count = TccServiceRegistry.GetServiceNames().Count();
        /// _logger.LogInformation($"已注册TCC服务数量: {count}");
        /// ```
        ///
        /// 注意事项：
        /// - 返回的集合是只读的（不能修改）
        /// - 集合是ConcurrentDictionary.Keys，线程安全
        /// - 集合可能在遍历过程中被其他线程修改
        /// - 返回的是服务名称，不是服务实例
        /// </summary>
        /// <returns>所有服务名称的集合</returns>
        public static IEnumerable<string> GetServiceNames()
        {
            return _services.Keys;
        }

        /// <summary>
        /// 清空所有服务
        ///
        /// 移除注册表中的所有TCC服务。
        ///
        /// 执行流程：
        /// 1. 调用_services.Clear()清空字典
        ///
        /// 调用时机：
        /// - 应用关闭时清理资源
        /// - 测试环境清理测试数据
        /// - 动态重新加载所有服务时
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：应用关闭时清理
        /// public async Task OnApplicationShutdownAsync()
        /// {
        ///     _logger.LogInformation("清空所有TCC服务");
        ///     TccServiceRegistry.Clear();
        /// }
        ///
        /// // 示例2：测试结束后清理
        /// [TestCleanup]
        /// public void Cleanup()
        /// {
        ///     TccServiceRegistry.Clear();
        /// }
        ///
        /// // 示例3：重新加载服务
        /// public void ReloadServices()
        /// {
        ///     TccServiceRegistry.Clear();
        ///     TccServiceRegistry.RegisterService(new OrderTccService());
        ///     TccServiceRegistry.RegisterService(new InventoryTccService());
        /// }
        /// ```
        ///
        /// 注意事项：
        /// - 清空后所有服务的Confirm/Cancel将无法执行
        /// - 应该确保没有正在执行的事务
        /// - 清空后需要重新注册所有服务
        /// - 线程安全，可以并发调用
        /// - 通常只在应用关闭或测试环境中使用
        /// </summary>
        public static void Clear()
        {
            _services.Clear();
        }
    }

    /// <summary>
    /// TCC事务拦截器
    /// </summary>
    public class TccTransactionInterceptor
    {
        private readonly ITccTransactionManager _transactionManager;
        private readonly ILogger<TccTransactionInterceptor> _logger;

        public TccTransactionInterceptor(
            ITccTransactionManager transactionManager,
            ILogger<TccTransactionInterceptor> logger)
        {
            _transactionManager = transactionManager;
            _logger = logger;
        }

        /// <summary>
        /// 执行TCC事务
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="parameters">参数</param>
        /// <param name="tryAction">Try动作</param>
        /// <param name="timeoutMs">超时时间</param>
        /// <returns>执行结果</returns>
        public async Task<object> ExecuteAsync(
            string serviceName,
            string methodName,
            Dictionary<string, object> parameters,
            Func<TccActionContext, Task<object>> tryAction,
            int timeoutMs = 60000)
        {
            var xid = RootContext.GetXid();

            _logger.LogDebug($"执行TCC事务: Service={serviceName}, Method={methodName}, Timeout={timeoutMs}");

            // 如果已经在全局事务中，则直接执行Try方法
            if (!string.IsNullOrEmpty(xid))
            {
                _logger.LogDebug($"已在全局事务中，直接执行Try方法: XID={xid}");

                var actionContext = new TccActionContext
                {
                    ServiceName = serviceName,
                    MethodName = methodName,
                    Parameters = parameters
                };

                return await tryAction(actionContext);
            }

            // 开始新的全局事务
            var beginResult = await _transactionManager.BeginAsync(timeoutMs, $"{serviceName}.{methodName}");

            if (!beginResult.Success)
            {
                _logger.LogError($"开始TCC事务失败: Message={beginResult.Message}");
                throw new TransactionException($"开始TCC事务失败: {beginResult.Message}");
            }

            var newXid = beginResult.Xid;
            RootContext.Bind(newXid);

            try
            {
                // 创建动作上下文
                var actionContext = new TccActionContext
                {
                    ServiceName = serviceName,
                    MethodName = methodName,
                    Parameters = parameters
                };

                // 执行Try方法
                var tryResult = await tryAction(actionContext);
                actionContext.TryResult = tryResult;

                // 序列化动作上下文
                var actionContextJson = JsonSerializer.Serialize(actionContext);

                // 注册分支事务
                var registerResult = await _transactionManager.RegisterBranchAsync(newXid, serviceName, actionContextJson);

                if (!registerResult.Success)
                {
                    _logger.LogError($"注册TCC分支事务失败: XID={newXid}, ServiceName={serviceName}, Message={registerResult.ErrorMessage}");
                    throw new TransactionException($"注册TCC分支事务失败: {registerResult.ErrorMessage}");
                }

                // 提交全局事务
                var commitResult = await _transactionManager.CommitAsync(newXid);

                if (!commitResult.Success)
                {
                    _logger.LogError($"提交TCC事务失败: XID={newXid}, Message={commitResult.Message}");
                    throw new TransactionException($"提交TCC事务失败: {commitResult.Message}");
                }

                _logger.LogDebug($"TCC事务已提交: XID={newXid}");
                return tryResult;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"TCC事务执行异常，开始回滚: XID={newXid}");

                // 回滚全局事务
                var rollbackResult = await _transactionManager.RollbackAsync(newXid);

                if (!rollbackResult.Success)
                {
                    _logger.LogError($"回滚TCC事务失败: XID={newXid}, Message={rollbackResult.Message}");
                }
                else
                {
                    _logger.LogDebug($"TCC事务已回滚: XID={newXid}");
                }

                throw;
            }
            finally
            {
                // 清理上下文
                RootContext.Unbind();
            }
        }
    }

    /// <summary>
    /// TCC上下文 - 简化版，用于方法参数传递
    /// </summary>
    public class TccContext
    {
        private static readonly AsyncLocal<TccContext> _current = new AsyncLocal<TccContext>();

        /// <summary>
        /// 全局事务ID
        /// </summary>
        public string Xid { get; set; }

        /// <summary>
        /// 分支ID
        /// </summary>
        public long BranchId { get; set; }

        /// <summary>
        /// 事务数据
        /// </summary>
        public Dictionary<string, object> Data { get; set; } = new Dictionary<string, object>();

        /// <summary>
        /// 当前TCC上下文
        /// </summary>
        public static TccContext Current
        {
            get
            {
                if (_current.Value == null)
                {
                    _current.Value = new TccContext
                    {
                        Xid = RootContext.GetXid()
                    };
                }
                return _current.Value;
            }
            set => _current.Value = value;
        }

        /// <summary>
        /// 清除当前上下文
        /// </summary>
        public static void Clear()
        {
            _current.Value = null;
        }
    }

    /// <summary>
    /// CommitMethod 属性 - 标记TCC的Confirm方法
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class CommitMethodAttribute : Attribute
    {
        /// <summary>
        /// Confirm方法名称
        /// </summary>
        public string Name { get; set; }

        public CommitMethodAttribute(string name = null)
        {
            Name = name;
        }
    }

    /// <summary>
    /// RollbackMethod 属性 - 标记TCC的Cancel方法
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class RollbackMethodAttribute : Attribute
    {
        /// <summary>
        /// Cancel方法名称
        /// </summary>
        public string Name { get; set; }

        public RollbackMethodAttribute(string name = null)
        {
            Name = name;
        }
    }

    /// <summary>
    /// TccAction 属性 - 标记TCC动作方法
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class TccActionAttribute : Attribute
    {
        /// <summary>
        /// 动作名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Commit方法名称
        /// </summary>
        public string CommitMethod { get; set; }

        /// <summary>
        /// Rollback方法名称
        /// </summary>
        public string RollbackMethod { get; set; }

        public TccActionAttribute(string name = null, string commitMethod = null, string rollbackMethod = null)
        {
            Name = name;
            CommitMethod = commitMethod;
            RollbackMethod = rollbackMethod;
        }
    }

    /// <summary>
    /// GlobalTransactional 属性 - 标记全局事务方法
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
    public class GlobalTransactionalAttribute : Attribute
    {
        /// <summary>
        /// 事务名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 超时时间（毫秒）
        /// </summary>
        public int Timeout { get; set; } = 60000;

        /// <summary>
        /// 是否回滚
        /// </summary>
        public bool Rollback { get; set; } = true;

        /// <summary>
        /// 事务传播行为
        /// </summary>
        public TransactionPropagationBehavior Propagation { get; set; } = TransactionPropagationBehavior.Required;

        /// <summary>
        /// 回滚异常类型
        /// </summary>
        public Type[] RollbackFor { get; set; }

        public GlobalTransactionalAttribute(string name = null, int timeout = 60000)
        {
            Name = name;
            Timeout = timeout;
        }
    }

    /// <summary>
    /// 事务传播行为
    /// </summary>
    public enum TransactionPropagationBehavior
    {
        /// <summary>
        /// 如果当前存在事务，则加入该事务；如果当前没有事务，则创建一个新的事务
        /// </summary>
        Required,

        /// <summary>
        /// 如果当前存在事务，则加入该事务；如果当前没有事务，则以非事务方式执行
        /// </summary>
        Supports,

        /// <summary>
        /// 如果当前存在事务，则加入该事务；如果当前没有事务，则抛出异常
        /// </summary>
        Mandatory,

        /// <summary>
        /// 创建一个新的事务，如果当前存在事务，则挂起当前事务
        /// </summary>
        RequiresNew,

        /// <summary>
        /// 以非事务方式执行，如果当前存在事务，则挂起当前事务
        /// </summary>
        NotSupported,

        /// <summary>
        /// 以非事务方式执行，如果当前存在事务，则抛出异常
        /// </summary>
        Never,

        /// <summary>
        /// 如果当前存在事务，则在嵌套事务内执行；如果当前没有事务，则创建一个新的事务
        /// </summary>
        Nested
    }

    /// <summary>
    /// Propagation 别名 - 用于属性参数
    /// </summary>
    public static class Propagation
    {
        public const TransactionPropagationBehavior Required = TransactionPropagationBehavior.Required;
        public const TransactionPropagationBehavior Supports = TransactionPropagationBehavior.Supports;
        public const TransactionPropagationBehavior Mandatory = TransactionPropagationBehavior.Mandatory;
        public const TransactionPropagationBehavior RequiresNew = TransactionPropagationBehavior.RequiresNew;
        public const TransactionPropagationBehavior NotSupported = TransactionPropagationBehavior.NotSupported;
        public const TransactionPropagationBehavior Never = TransactionPropagationBehavior.Never;
        public const TransactionPropagationBehavior Nested = TransactionPropagationBehavior.Nested;
    }

    /// <summary>
    /// RollbackFor 别名 - 用于属性参数
    /// </summary>
    public static class RollbackFor
    {
        public static Type[] Any = new[] { typeof(Exception) };
        public static Type[] None = Array.Empty<Type>();
    }
}